#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "MSTK.h"
#include <mpi.h>

#ifdef __cplusplus
extern "C" {
#endif


int MESH_Vol_SendMesh(Mesh_ptr mesh, int rank, MPI_Comm comm) {
  int i, j, k, idx, max_nfv;
  int nv, ne, nf, nfv, nfe;
  MVertex_ptr mv, vertex, global_mv;
  MEdge_ptr me, global_me;
  MFace_ptr mf, global_mf;
  List_ptr mfverts, mfedges;
  double xyz[3];
  /* basic mesh information */
  RepType rtype = MESH_RepType(mesh);
  nv = MESH_Num_Vertices(mesh);
  ne = MESH_Num_Edges(mesh);
  nf = MESH_Num_Faces(mesh);


  /* collect data */
  struct PVertex *list_vertex = (PVertex *)MSTK_malloc(nv*sizeof(PVertex));
  for(i = 0; i < nv; i++) {
    mv = MESH_Vertex(mesh,i);
    MV_to_PV(mv,&list_vertex[i]);
  }
    


  /* construct derived datatype */
  MPI_Datatype PVertex_MPI;
  int pvertex_lengths[4] = {3,1,1,1};
  MPI_Aint pvertex_disps[4];
			    
  MPI_Get_address(list_vertex,pvertex_disps);
  MPI_Get_address(&(list_vertex[0].gid_gdim),pvertex_disps+1);
  MPI_Get_address(&(list_vertex[0].parid_ptype),pvertex_disps+2);
  MPI_Get_address(&(list_vertex[0].globalid),pvertex_disps+3);
  int base = pvertex_disps[0];
  for(i = 0; i < 4; i++) 
    pvertex_disps[i] -= base;

  MPI_Datatype pvertex_types[4] = {MPI_DOUBLE,MPI_INT,MPI_INT,MPI_INT};
  MPI_Type_create_struct(4,pvertex_lengths,pvertex_disps,pvertex_types,&PVertex_MPI);
  MPI_Type_commit(&PVertex_MPI);

  MPI_Send(list_vertex,nv,PVertex_MPI,rank,rank,comm);
  
  return 1;
}
  
#ifdef __cplusplus
}
#endif

